/*
 * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java,v 1.7 2004/06/11 19:26:27 olegk Exp $
 * $Revision: 480424 $
 * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
 * 
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package gcontent.channel.http.ssl;

import java.io.IOException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;



import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

public class MySSLSocketFactory  {
	
    private static class MyX509HostnameVerifier implements X509HostnameVerifier {

        private boolean fired = false;

        public boolean verify(String host, SSLSession session) {
            return true;
        }

        public void verify(String host, SSLSocket ssl) throws IOException {
            this.fired = true;
        }

        public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
        }

        public void verify(String host, X509Certificate cert) throws SSLException {
        }

        public boolean isFired() {
            return this.fired;
        }

    }
    
    private static class X509TrustManager implements javax.net.ssl.X509TrustManager
    {
        private javax.net.ssl.X509TrustManager standardTrustManager = null;

        /** Log object for this class. */
        private static final Log LOG = LogFactory.getLog(X509TrustManager.class);

        /**
         * Constructor for EasyX509TrustManager.
         */
        public X509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
            super();
            TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            factory.init(keystore);
            TrustManager[] trustmanagers = factory.getTrustManagers();
            if (trustmanagers.length == 0) {
                throw new NoSuchAlgorithmException("no trust manager found");
            }
            this.standardTrustManager = (javax.net.ssl.X509TrustManager)trustmanagers[0];
        }

        /**
         * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
         */
        public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
            standardTrustManager.checkClientTrusted(certificates,authType);
        }

        /**
         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
         */
        public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
            if ((certificates != null) && LOG.isDebugEnabled()) {
                LOG.debug("Server certificate chain:");
                for (int i = 0; i < certificates.length; i++) {
                    LOG.debug("X509Certificate[" + i + "]=" + certificates[i]);
                }
            }
            /* NOT CHECKS, CERTIFICATES ALWAYS ARE TRUSTED */
            /*
            if ((certificates != null) && (certificates.length == 1)) {
                certificates[0].checkValidity();
            } else {
            	
                standardTrustManager.checkServerTrusted(certificates,authType);
            }
            */
        }

        /**
         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
         */
        public X509Certificate[] getAcceptedIssuers() {
            return this.standardTrustManager.getAcceptedIssuers();
        }
    }    
    
    public static boolean register(HttpClient http_cli, URL url) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException
    {	
    	Scheme https_sc;
    	SSLSocketFactory ssl_fac;
    	SSLContext sslcontext;
    	TrustManager[] trustmanagers;    	
    	int port;
    	
    	if(!url.getProtocol().equals("https"))
    		return false;
    	
    	port = url.getPort();
    	
    	if(port == -1)
    		port = url.getDefaultPort();
    	        
    	trustmanagers = new TrustManager[1];
    	trustmanagers[0] = new X509TrustManager(KeyStore.getInstance("JKS"));
    	    	
        sslcontext = SSLContext.getInstance("TLSv1");
        sslcontext.init(null, trustmanagers, null);
    	ssl_fac = new SSLSocketFactory(sslcontext);
    	ssl_fac.setHostnameVerifier(new MyX509HostnameVerifier());

    	https_sc = new Scheme(url.getProtocol(), ssl_fac, port);
        http_cli.getConnectionManager().getSchemeRegistry().register(https_sc);
        
        return true;
    }

}

